#pragma once
#include <iostream>
#include <vector>
#include <queue>
#include "Mutex.hpp"
#include "Thread.hpp"
#include "Log.hpp"
#include "Cond.hpp"
namespace ThreadPoolModule
{
    using namespace threadModlue;
    using namespace Mutex;
    using namespace CondModule;
    using namespace LogModle;
    template <typename T>
    class ThreadPool
    {
    private:
        static const int defultcap = 5;
        void HanderTask()
        {
            char buffer[128];
            pthread_getname_np(pthread_self(), buffer, sizeof(buffer));
            std::string name(buffer);
            while (true)
            {
                LockGuard lock(_mutex);
                while (_task_queue.size() == 0 && _isrunning)
                {
                    _sleep_num++;
                    _cond.Wait(_mutex);
                    _sleep_num--;
                }
                if (_task_queue.size() == 0 && !_isrunning)
                {
                    _mutex.UnLock();
                    break;
                }
                T task = _task_queue.front();
                _task_queue.pop();
                task();
                LOG(LogLever::DEBUG) << name << "执行了一个任务";
            }
        }
        

    public:
        ThreadPool(int cap = defultcap)
            : _cap(cap),
              _isrunning(false),
              _sleep_num(0)
        {
            LOG(LogLever::DEBUG)<<"ThreadPool Creat";
            for (int i = 0; i < _cap; i++)
            {
                _threads.emplace_back(
                    [this]()
                    {
                        HanderTask();
                    });
            }
        }
        void Start()
        {
            // LockGuard lock(_mutex);
            _isrunning = true;
            for (auto &thread : _threads)
            {
                thread.Start();
                LOG(LogLever::DEBUG) << thread.GetStringOfName()<< "被启动";
            }
        }
        void Stop()
        {
            LockGuard lock(_mutex);
            _isrunning = false;
            _cond.NotifyAll();

            LOG(LogLever::DEBUG) << "线程池暂停中...";
        }
        void Wait()
        {
            for(auto& thread:_threads)
            {
                thread.join();
                LOG(LogLever::DEBUG) << thread.GetStringOfName()<< "已退出";
            }
            LOG(LogLever::DEBUG) << "线程池已退出";
        }
        bool Enqueue(const T& t)
        {
            bool ret = false;
            LockGuard lock(_mutex);
            if(_isrunning)
            {
                _task_queue.push(t);
                if(_sleep_num==_threads.size())
                {
                    _cond.Notify();
                }
                LOG(LogLever::DEBUG)<<"任务入队列成功";
                ret = true;
            }
            return ret;
        }
    private:
        std::vector<Thread> _threads;
        std::queue<T> _task_queue;
        int _cap;
        Cond _cond;
        MyMutex _mutex;
        bool _isrunning;
        int _sleep_num;
    };

}